/**
 * Copyright (c) 2006-2010 Spotify Ltd
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 *
 */

#define USER_AGENT "<Add your own useragent>"
#error Please update above variables for your project
/* A simple stub that logs in and out */

#include "main.h"
#include <pthread.h>
#include <sys/time.h>
#include <stdlib.h>
#include <stdio.h>
sp_session *g_session;

static int notify_events;
static pthread_mutex_t notify_mutex;
static pthread_cond_t notify_cond;


static void connection_error(sp_session *session, sp_error error)
{
	
}

static void logged_in(sp_session *session, sp_error error)
{
	//add your testcode here 
	
}

static void logged_out(sp_session *session)
{
	exit(0);
}


/**
 * This callback is called for log messages.
 *
 * @sa sp_session_callbacks#log_message
 */
static void log_message(sp_session *session, const char *data)
{
	fprintf(stderr,"%s",data);
}

void notify_main_thread(sp_session *session)
{
	pthread_mutex_lock(&notify_mutex);
	notify_events = 1;
	pthread_cond_signal(&notify_cond);
	pthread_mutex_unlock(&notify_mutex);
}

static sp_session_callbacks callbacks = {
	&logged_in,
	&logged_out,
	NULL,
	&connection_error,
	NULL,
	&notify_main_thread,
	NULL,
	NULL,
	&log_message
};

int spotify_init(const char *username,const char *password)
{
	sp_session_config config;
	sp_error error;
	sp_session *session;
	
	/// The application key is specific to each project, and allows Spotify
	/// to produce statistics on how our service is used.
	extern const char g_appkey[];
	/// The size of the application key.
	extern const size_t g_appkey_size;

	// Always do this. It allows libspotify to check for
	// header/library inconsistencies.
	config.api_version = SPOTIFY_API_VERSION;

	// The path of the directory to store the cache. This must be specified.
	// Please read the documentation on preferred values.
	config.cache_location = "tmp";

	// The path of the directory to store the settings. 
	// This must be specified.
	// Please read the documentation on preferred values.
	config.settings_location = "tmp";

	// The key of the application. They are generated by Spotify,
	// and are specific to each application using libspotify.
	config.application_key = g_appkey;
	config.application_key_size = g_appkey_size;

	// This identifies the application using some
	// free-text string [1, 255] characters.
	config.user_agent = USER_AGENT;

	// Register the callbacks.
	config.callbacks = &callbacks;

	error = sp_session_create(&config, &session);
	if (SP_ERROR_OK != error) {
		fprintf(stderr, "failed to create session: %s\n",
		                sp_error_message(error));
		return 2;
	}

	// Login using the credentials given on the command line.
	error = sp_session_login(session, username, password, 0);

	if (SP_ERROR_OK != error) {
		fprintf(stderr, "failed to login: %s\n",
		                sp_error_message(error));
		return 3;
	}

	g_session = session;
	return 0;
}

int main(int argc, char **argv)
{
	int next_timeout = 0;
	if(argc < 3) {
		fprintf(stderr,"Usage: %s <username> <password>\n",argv[0]);
	}
	pthread_mutex_init(&notify_mutex, NULL);
	pthread_cond_init(&notify_cond, NULL);

	if(spotify_init(argv[1],argv[2]) != 0) {
		fprintf(stderr,"Spotify failed to initialize\n");
		exit(-1);
	}
	pthread_mutex_lock(&notify_mutex);
	for (;;) {
		if (next_timeout == 0) {
			while(!notify_events)
				pthread_cond_wait(&notify_cond, &notify_mutex);
		} else {
			struct timespec ts;

	#if _POSIX_TIMERS > 0
			clock_gettime(CLOCK_REALTIME, &ts);
	#else
			struct timeval tv;
			gettimeofday(&tv, NULL);
			TIMEVAL_TO_TIMESPEC(&tv, &ts);
	#endif

			ts.tv_sec += next_timeout / 1000;
			ts.tv_nsec += (next_timeout % 1000) * 1000000;

			while(!notify_events) {
				if(pthread_cond_timedwait(&notify_cond, &notify_mutex, &ts))
					break;
			}
		}

		// Process libspotify events
		notify_events = 0;
		pthread_mutex_unlock(&notify_mutex);

		do {
			sp_session_process_events(g_session, &next_timeout);
		} while (next_timeout == 0);

		pthread_mutex_lock(&notify_mutex);
	}
	return 0;
}
